﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Catalog.API.Infrastructure;
using Catalog.API.IntegrationEvents;
using Catalog.API.Model;
using Catalog.API.ViewModel;
using EventBus.Extensions;
using HttpLib.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Paging;

namespace Catalog.API.Controllers
{
    [Route("api/v1/[controller]")]
    [ApiController]
    [Authorize]
    public class CatalogController : ControllerBase
    {
        private readonly CatalogContext _catalogContext;
        private readonly CatalogSettings _settings;
        private readonly IIdentityService _identityService;
        private readonly ILogger<CatalogController> _logger;
        private readonly ICatalogIntegrationEventService _catalogIntegrationEventService;
        public CatalogController(CatalogContext context, 
            IOptionsSnapshot<CatalogSettings> settings, 
            ICatalogIntegrationEventService catalogIntegrationEventService,
            IIdentityService identityService,
            ILogger<CatalogController> logger)
        {
            _catalogContext = context ?? throw new ArgumentNullException(nameof(context));
            _catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService));
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _settings = settings.Value;

            //context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        }
        [Route("store")]
        [HttpGet]
        [ProducesResponseType(typeof(PaginatedItemsViewModel<ExpressStore>), (int)HttpStatusCode.OK)]
        [ProducesResponseType(typeof(ExpressStore), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<ActionResult<PaginatedItemsViewModel<ExpressStore>>> GetExpressStore(ExpressStoreFilter filter)
        {
            var total = await _catalogContext.ExpressStores.Where(t => t.Status == 0).LongCountAsync();
            var itemsOnPage = await _catalogContext.ExpressStores
                .OrderBy(c => c.Name)
                .Skip(filter.PageSize * filter.PageIndex)
                .Take(filter.PageSize)
                .ToListAsync();
            var model = new PaginatedItemsViewModel<ExpressStore>(filter.PageIndex, filter.PageSize, total, itemsOnPage);

            return Ok(model);
        }

        [Route("store")]
        [HttpPost]
        [ProducesResponseType(typeof(ExpressStore), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> AddExpressStore([FromBody] ExpressStoreRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                ExpressStore expressStore = new ExpressStore(request.Name, request.Phone, request.OwnerId, request.ContactMan, userId);
                _catalogContext.ExpressStores.Add(expressStore);
                int result = await _catalogContext.SaveChangesAsync();
                if(result > 0)
                {
                    _logger.LogInformation(
                        "----- Add ExpressStore Succeed: {ExpressStore} - {IdProperty}: {LocationId} ({@ExpressStore})",
                        expressStore.GetGenericTypeName(),
                        nameof(expressStore.Id),
                        expressStore.Id,
                        expressStore);
                    return Ok();
                }
                else
                {
                    _logger.LogError(
                        "----- Add ExpressStore Error: {ExpressStore} - {IdProperty}: {LocationId} ({@ExpressStore})",
                        expressStore.GetGenericTypeName(),
                        nameof(expressStore.Id),
                        expressStore.Id,
                        expressStore);
                    return BadRequest();
                }
            }
            catch(Exception e)
            {
                _logger.LogError($"----- Add ExpressStore Error,Message:{e.Message},parameter:{request}");
                return BadRequest();
            }
        }
        /// <summary>
        /// 更新快递店
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [Route("store")]
        [HttpPut]
        [ProducesResponseType(typeof(ExpressStore), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> UpdateExpressStore([FromBody] ExpressStoreRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                var expressStore = await _catalogContext.ExpressStores.Where(t => t.ExpressStoreCode == request.ExpressStoreCode).FirstOrDefaultAsync();
                if(expressStore != null)
                {
                    expressStore.Name = request.Name;
                    expressStore.Phone = request.Phone;
                    expressStore.OwnerId = request.OwnerId;
                    expressStore.ContactMan = request.ContactMan;
                    expressStore.UpdateTime = DateTime.Now;
                    expressStore.ModifyUserId = userId;
                    _catalogContext.ExpressStores.Update(expressStore);
                    await _catalogContext.SaveChangesAsync();
                    _logger.LogInformation(
                        "----- Update ExpressStore Succeed: {ExpressStore} - {IdProperty}: {LocationId} ({@ExpressStore})",
                        expressStore.GetGenericTypeName(),
                        nameof(expressStore.Id),
                        expressStore.Id,
                        expressStore);
                    return Ok();
                }
                else
                {
                    _logger.LogError($"----- Update ExpressStore Error: can not find ExpressStore where ExpressStoreCode equal {request.ExpressStoreCode}");
                    return BadRequest();
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"----- Add ExpressStore Error,Message:{e.Message},parameter:{request}");
                return BadRequest();
            }
        }
    }
}
